﻿using System;
using System.IO;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // if no arguments
                if (args.Length == 0)
                    throw new Exception("Expecting valid path to KStubs procedures xml");
                // validate first argument, expecting path to procedures.xml
                if (!File.Exists(args[0]))
                    throw new Exception("Expecting valid path to KStubs procedures xml");
                // validate third argument, exepecting procedure name
                if (args.Length < 2)
                    throw new Exception("Expecting valid procedure name");

                Run2(args[0], args[1]);
            }
            catch (Exception unhandled)
            {
                Console.WriteLine(unhandled.Message);
                Exception inner = unhandled.InnerException;

                while (inner != null)
                {
                    Console.WriteLine(unhandled.Message);
                    inner = inner.InnerException;
                }
            }

        }

        /// <summary>
        /// This is my implementation routine, and demonstrates the use of the Schema backend
        /// To demonstrate my approach to meeting the new requirements, without changing user 
        /// input, I have created a Run2 method (below) that would operate against the new
        /// database objects once they are executed.
        /// </summary>
        /// <param name="ProceduresFile"></param>
        /// <param name="ProcedureName"></param>
        static void Run(String ProceduresFile, String ProcedureName)
        {
            Console.WriteLine("Running Procedure: {0}, hit <enter> to continue..", ProcedureName);
            Console.ReadLine();

            using (KStubs.KSConnectionClass conn = new KStubs.KSConnectionClass(ConfigurationManager.ConnectionStrings["local"].ConnectionString))
            {
                KStubs.Schema.procedures procedures = KStubs.Schema.procedures.LoadFromFile(ProceduresFile);
                KStubs.Schema.procedure procedure = procedures.getProcedure(ProcedureName);

                if (procedure == null)
                    throw new Exception(String.Format("Procedure not supported: {0}", ProcedureName));

                KStubs.KSQueryClass query = new KStubs.KSQueryClass(conn, procedure);
                
                query.Run();

                Console.WriteLine("Result: {0}", query.Result);
                Console.WriteLine("Records {0}", query.RecordsAffected);

                if (procedure.command.action == KStubs.Schema.actionType.Insert)
                    Console.WriteLine("Last Record ID: {0}", query.LastRecordID);

                if (query.UnhandledException != null)
                {
                    Console.WriteLine("====Unhandled Exceptions Occured in CodeProject====");
                    Console.WriteLine(query.UnhandledException.Message);
                    Exception inner = query.UnhandledException.InnerException;

                    while (inner != null)
                    {
                        Console.WriteLine(query.UnhandledException.Message);
                        inner = inner.InnerException;
                    }

                }
                else
                {
                    string outfile = "out\\" + procedure.name + "_" + DateTime.Now.ToFileTimeUtc().ToString() + ".xml";
                    procedure.SaveToFile(outfile);

                    Console.WriteLine("Saved Result To: {0}", outfile);
                }

            }

        }

        static void Run2(String ProceduresFile, String ProcedureName)
        {
            Console.WriteLine("Running Procedure: {0}, hit <enter> to continue..", ProcedureName);
            Console.ReadLine();

            using (KStubs.KSConnectionClass conn = new KStubs.KSConnectionClass(ConfigurationManager.ConnectionStrings["local"].ConnectionString))
            {
                KStubs.Schema.procedures procedures = KStubs.Schema.procedures.LoadFromFile(ProceduresFile);
                KStubs.Schema.procedure procedure = procedures.getProcedure(ProcedureName);

                if (procedure == null)
                    throw new Exception(String.Format("Procedure not supported: {0}", ProcedureName));

                KStubs.KSQueryClass query = new KStubs.KSQueryClass(conn, procedure);

                // I know this feels like a kludge, and final implementation would really be much different than this
                // but you can see that in this implementation example I am manipulating user input, changing the parameters
                // to achieve first_name and last_name parameters.  So, user input stays the same.

                if(procedure.name == "AddEmployee")
                {
                    KStubs.Schema.parameter fname_parm = new KStubs.Schema.parameter();
                    KStubs.Schema.parameter lname_parm = new KStubs.Schema.parameter();

                    fname_parm.name = "FirstName";
                    lname_parm.name = "LastName";

                    var name_parm = procedure.getParameter("Name");
                    string name = name_parm.value;
                    int indexof = name.IndexOf(' ');
                    if (indexof > 0)
                    {
                        fname_parm.value = name.Substring(0, indexof).Trim();
                        lname_parm.value = name.Substring(indexof).Trim();
                    }
                    procedure.parameters.Add(fname_parm);
                    procedure.parameters.Add(lname_parm);
                    procedure.parameters.Remove(name_parm);

                }

                query.Run();

                Console.WriteLine("Result: {0}", query.Result);
                Console.WriteLine("Records {0}", query.RecordsAffected);

                if (procedure.command.action == KStubs.Schema.actionType.Insert)
                    Console.WriteLine("Last Record ID: {0}", query.LastRecordID);

                if (query.UnhandledException != null)
                {
                    Console.WriteLine("====Unhandled Exceptions Occured in CodeProject====");
                    Console.WriteLine(query.UnhandledException.Message);
                    Exception inner = query.UnhandledException.InnerException;

                    while (inner != null)
                    {
                        Console.WriteLine(query.UnhandledException.Message);
                        inner = inner.InnerException;
                    }

                }
                else
                {
                    string outfile = "out\\" + procedure.name + "_" + DateTime.Now.ToFileTimeUtc().ToString() + ".xml";
                    procedure.SaveToFile(outfile);

                    Console.WriteLine("Saved Result To: {0}", outfile);
                }

            }

        }
    }
}
